#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QDockWidget>
#include <QFileDialog>
#include <QString>
#include <QLabel>
#include <QTextStream>
#include <QAudioEncoderSettings>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    mHash = new QHash<QString,CustomData>;
    mOpenGLWidget = new OpenGLWidget;

    QHBoxLayout *container = new QHBoxLayout;
    container->addWidget(mOpenGLWidget);

    QWidget *centralW = new QWidget;
    delete centralW->layout();
    centralW->setLayout(container);
    setCentralWidget(centralW);

    QDockWidget *dockWidget = new QDockWidget(this);
    dockWidget->setWindowTitle("Data Setting");
    QWidget *dockContentWidget = new QWidget;

    QPushButton *btnSetFolder = new QPushButton(dockWidget);
    btnSetFolder->setText("Setting Folder");
    //    btnSetFolder->setFixedWidth(100);

    btnAnimation = new QPushButton(dockWidget);
    btnAnimation->setText("Display Animation");
    //    btnAnimation->setFixedWidth(100);
    btnSaveAnimation=  new QPushButton(dockWidget);
    btnSaveAnimation->setText("Save Animation");
    btnSaveAnimation->setEnabled(false);

    QLabel *labelSource = new QLabel(dockWidget);
    labelSource->setText("Data Source:");

    lableFEMParams = new QLabel("String Params:");
    cbBoxFEMParams =  new QComboBox;

    listWidget = new QListWidget;
    listWidget->setFixedWidth(150);
    listWidget->setFixedHeight(280);
    QVBoxLayout *layout1 = new QVBoxLayout(dockWidget);
    layout1->addWidget(btnSetFolder);
    layout1->addWidget(btnAnimation);
    layout1->addWidget(btnSaveAnimation);
    layout1->addWidget(labelSource);
    layout1->addWidget(listWidget);
    layout1->addWidget(lableFEMParams);
    layout1->addWidget(cbBoxFEMParams);

    layout1->setSizeConstraint(QLayout::SetFixedSize);
    delete dockContentWidget->layout();
    dockContentWidget->setLayout(layout1);

    dockWidget->setFeatures(QDockWidget::DockWidgetMovable );
    dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

    addDockWidget(Qt::RightDockWidgetArea,dockWidget);

    dockWidget->setWidget(dockContentWidget);

    setWindowTitle("Chart 3D");
    setMinimumSize(800,600);

    connect(btnSetFolder,&QPushButton::clicked,this,&MainWindow::btnSettingFolder);
    connect(listWidget,&QListWidget::currentRowChanged,this,&MainWindow::currentRowChanged);
    connect(btnAnimation,&QPushButton::clicked,this,&MainWindow::btnAnimationClicked);
    //connect(this,&MainWindow::TriggerAnimation,mOpenGLWidget,&OpenGLWidget::triggerAnimation);
    connect(cbBoxFEMParams,static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),mOpenGLWidget,&OpenGLWidget::cbBoxFEMParamsChanged);

    connect(btnSaveAnimation,&QPushButton::clicked,mOpenGLWidget,&OpenGLWidget::saveAnimation);
}

MainWindow::~MainWindow()
{

}

void MainWindow::btnSettingFolder()
{
    m_StrPath = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                  "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if(m_StrPath.isEmpty() | m_StrPath.isNull())
        return;

    QDir dir(m_StrPath);
    int index=0;
    dir.setFilter( QDir::Files | QDir::NoSymLinks);
    QFileInfoList subDir = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);

    mHash->clear();
    QStringList lstName;
    for(int i=0;i<subDir.count();i++)
    {
        QString strDir = subDir.at(i).absoluteFilePath();
        dir=QDir(strDir);
        QStringList strCur = strDir.split('/');
        QString name =strCur.last();
        index = strCur.last().remove("movoutput").toInt();


        lstName.insert(index-1,name);
        mHash->insert(name,LoadData(strDir));
    }

    listWidget->clear();
    listWidget->addItems(lstName);

    listWidget->setCurrentRow(0);

    if(mHash->count()!=0)
    {
        CustomData data = mHash->value(listWidget->item(0)->text());
        QList<QString> lstName =data.GetFEMParams();
        QStringList strList;

        QList<int> lstIndex;
        QList<QString> lstSubName;
        for(int i=0;i<lstName.count();i++)
        {
            QStringList  lstTemp = lstName.at(i).split('_');
            int index = lstTemp.at(lstTemp.count()-1).toInt();
            lstIndex.append(index);
            lstSubName.append(lstTemp.at(0));
        }

        for(int i=0;i<lstName.count();i++)
        {
            int index = lstIndex.indexOf(i);
            strList<<lstSubName[index];
        }

        cbBoxFEMParams->addItems(strList);
    }
}

QList<QList<float>> MainWindow::readData(QString strname)
{
    QFile file(strname);
    QList<QList<float>> lst;
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine();
            QStringList lstStr =  line.split('\t');
            QList<float> temp;
            for(int i =0; i<lstStr.count()-1;i++)
            {
                temp.append(lstStr[i].toDouble());
            }
            lst.append(temp);
        }
    }

    return lst;
}

QHash<QString,QVector<double>>  MainWindow::readStringFEMData(QString strname)
{
    QFile file(strname);
    QStringList stringFEMName;
    //stringFEMName.clear();
    QList<QList<double>> lstData;
    QHash<QString,QVector<double>> stringFEMData;
    int index = 0;
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine();
            QStringList lstStr =  line.split('\t');
            if(index == 0)
            {
                for(int i=0;i<lstStr.count()-1;i++)
                {
                    QVector<double> temp;
                    QString tempName = lstStr[i]+"_"+ QString::number(i);
                    stringFEMName << tempName;
                    //stringFEMData.insert(tempName,temp);
                }
            }
            else
            {
                QList<double> lstRow;
                for(int i=0;i<stringFEMName.count();i++)
                {
                    double data = lstStr[i].toDouble();
                    lstRow.append(data);
                }

                lstData.append(lstRow);
            }

            index++;
        }
    }

    for(int i=0;i<lstData.at(0).count();i++)
    {
        QVector<double> vec;
        for(int j=0;j<lstData.count();j++)
        {
            vec.append(lstData.at(j).at(i));
        }
        stringFEMData.insert(stringFEMName.at(i),vec);
    }

    //    for(int i=0;i<stringFEMName.count();i++)
    //    {
    //        stringFEMData.insert(stringFEMName.at(i),lstData.at(i).toVector());
    //    }

    return stringFEMData;
}

QHash<QString,QVector<double>>  MainWindow::readTouchData(QString strname)
{
    QFile file(strname);

    QHash<QString,QVector<double>> touchData;

    int index = 0;
    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine();
            QStringList lstStr =  line.split('\t');
            if(index == 0)
            {
                for(int i=0;i<lstStr.count()-1;i++)
                {
                    QVector<double> temp;
                    //touchName << lstStr[i];
                    touchData.insert(lstStr[i],temp);
                }
            }
            else
            {
                QHash<QString,QVector<double>>::iterator iter;
                int i =0;
                for(iter = touchData.begin();iter!=touchData.end();iter++)
                {
                    iter.value().append(lstStr[i++].toDouble());
                }
            }

            index++;
        }
    }

    return touchData;
}

void MainWindow::currentRowChanged(int currentRow)
{
    mOpenGLWidget->AddData(mHash->value(listWidget->item(currentRow)->text()));
}

void MainWindow::btnAnimationClicked()
{
    if(btnAnimation->text() =="Display Animation")
    {
        btnSaveAnimation->setEnabled(false);
        btnAnimation->setText("Stop Animation");
        QList<CustomData> *lstData = new QList<CustomData>;

        for(int i=0;i<listWidget->count();i++)
        {
            lstData->append(mHash->value(listWidget->item(i)->text()));
        }
        mOpenGLWidget->AddMultiData(lstData);

        mOpenGLWidget->triggerAnimation(false);
    }
    else
    {
        btnAnimation->setText("Display Animation");

        mOpenGLWidget->triggerAnimation(true);
        btnSaveAnimation->setEnabled(true);
    }
}
CustomData MainWindow::LoadData(QString fileDir)
{
    CustomData data;
    QDir dir = QDir(fileDir);
    QFileInfoList files =  dir.entryInfoList(QDir::Files);

    QList<QList<float>> lstX,lstY,lstZ;
    QList<QList<float>> lstWellX,lstWellY,lstWellZ;

    for(int j = 0; j< files.count();j++)
    {
        QString strFile = files[j].absoluteFilePath();
        QStringList strCur = strFile.split('/');

        if(strCur.at(strCur.count()-1).contains("string3Dx"))
        {
            lstX = readData(strFile);
        }
        else if(strCur.at(strCur.count()-1).contains("string3Dy"))
        {
            lstY = readData(strFile);
        }
        else if(strCur.at(strCur.count()-1).contains("string3Dz"))
        {
            lstZ = readData(strFile);
        }
        else if(strCur.at(strCur.count()-1).contains("well3Dx"))
        {
            lstWellX = readData(strFile);
        }
        else if(strCur.at(strCur.count()-1).contains("well3Dy"))
        {
            lstWellY = readData(strFile);
        }
        else if(strCur.at(strCur.count()-1).contains("well3Dz"))
        {
            lstWellZ = readData(strFile);
        }

    }

    data.AddStringData(lstX,lstY,lstZ);
    data.AddWellData(lstWellX,lstWellY,lstWellZ);

    for(int j = 0; j< files.count();j++)
    {
        QString strFile = files[j].absoluteFilePath();
        QStringList strCur = strFile.split('/');

        if(strCur.at(strCur.count()-1).contains("stringFEM"))
        {
            data.AddStringFEMData(readStringFEMData(strFile));
        }
        else if(strCur.at(strCur.count()-1).contains("touchF"))
        {
            data.AddTouchData(readTouchData(strFile));
        }
    }
    return data;
}
